using Assets;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

public class TerrainGenerator : MonoBehaviour
{
    [SerializeField] int brushRadius;
    [SerializeField] float brushStrength;
    [SerializeField] float brushFallback;
    [SerializeField] int mapSize;
    [SerializeField] float gridScale;
    [SerializeField] float isoValue;
    [SerializeField] MeshFilter meshFilter;
    [SerializeField] MeshCollider meshCollider;
    float[,] grids;
    SquareMap squareMap;
    Mesh mesh;
    // Start is called before the first frame update
    void Start()
    {
        grids = new float[mapSize, mapSize];
        for (int x = 0; x < grids.GetLength(0); x++)
        {
            for (int y = 0; y < grids.GetLength(1); y++)
            {
                grids[x, y] = isoValue + 0.1f;
            }
        }
        squareMap = new SquareMap(mapSize - 1, gridScale, isoValue);
        mesh = new Mesh();
        meshFilter.sharedMesh = mesh;
        GenerateMesh();
    }
    private void OnDestroy()
    {
        if (mesh)
            Destroy(mesh);
    }
    public void Touching(Vector3 point)
    {
        point = transform.InverseTransformPoint(point);
        Vector2Int girdPos = GetGridPosition(point);
        if (brushRadius <= 0) return;
        bool reflush = false;
        for (int x = girdPos.x - brushRadius; x <= girdPos.x + brushRadius; x++)
        {
            for (int y = girdPos.y - brushRadius; y <= girdPos.y + brushRadius; y++)
            {
                Vector2Int gridIndex = new Vector2Int(x, y);
                if (IsValid(gridIndex))
                {
                    float distance = Vector2.Distance(gridIndex, girdPos);
                    float factor = brushStrength * Mathf.Exp(-distance * brushFallback / brushRadius);
                    grids[gridIndex.x, gridIndex.y] -= factor;
                    reflush = true;
                }
            }
        }
        if (reflush)
            GenerateMesh();
    }
    void GenerateMesh()
    {
        mesh.Clear();
        squareMap.Update(grids);
        mesh.SetVertices(squareMap.verts);
        mesh.SetTriangles(squareMap.tris, 0);
        if (meshCollider)
            meshCollider.sharedMesh = mesh;
    }
    bool IsValid(Vector2Int girdPos)
    {
        return (girdPos.x > -1 && girdPos.y > -1 && girdPos.x < mapSize && girdPos.y < mapSize);
    }
    Vector2 GetWorldPosition(int x, int y)
    {
        float offset = mapSize * gridScale * 0.5f - gridScale * 0.5f;
        return new Vector2(x, y) * gridScale - new Vector2(offset, offset);
    }
    Vector2Int GetGridPosition(Vector2 point)
    {
        Vector2Int vector2Int = new Vector2Int();
        vector2Int.x = Mathf.FloorToInt(point.x / gridScale + mapSize * gridScale * 0.5f - gridScale * 0.5f);
        vector2Int.y = Mathf.FloorToInt(point.y / gridScale + mapSize * gridScale * 0.5f - gridScale * 0.5f);
        return vector2Int;
    }
    //private void OnDrawGizmos()
    //{
    //    if (grids == null) return;
    //    Gizmos.color = Color.red;
    //    for (int x = 0; x < grids.GetLength(0); x++)
    //    {
    //        for (global::System.Int32 y = 0; y < grids.GetLength(1); y++)
    //        {
    //            Vector2 worldPoint = GetWorldPosition(x, y);
    //            Gizmos.DrawSphere(worldPoint, gridScale * 0.1f);
    //            Handles.Label(worldPoint + Vector2.up * gridScale * 0.33f, grids[x, y].ToString());
    //        }
    //    }
    //}
}
